/**
 * 基础实体抽象类
 * 定义所有实体的通用属性和方法
 */
export abstract class BaseEntity {
    /** 实体ID */
    public id: string;
    
    /** 创建时间 */
    public readonly createdAt: Date;
    
    /** 更新时间 */
    public updatedAt: Date;
    
    /** 版本号（用于乐观锁） */
    public version: number;

    constructor(id?: string) {
        this.id = id || this.generateId();
        this.createdAt = new Date();
        this.updatedAt = new Date();
        this.version = 1;
    }

    /**
     * 生成实体ID
     * 子类可重写此方法自定义ID生成规则
     */
    protected generateId(): string {
        return Date.now().toString(36) + Math.random().toString(36).substr(2);
    }

    /**
     * 更新实体
     * 自动更新时间戳和版本号
     */
    protected updateEntity(): void {
        this.updatedAt = new Date();
        this.version += 1;
    }

    /**
     * 验证实体
     * 子类应重写此方法实现具体验证逻辑
     */
    public validate(): ValidationResult {
        const errors: ValidationError[] = [];

        if (!this.id) {
            errors.push({ field: 'id', message: 'ID不能为空' });
        }

        if (!this.createdAt) {
            errors.push({ field: 'createdAt', message: '创建时间不能为空' });
        }

        return {
            isValid: errors.length === 0,
            errors
        };
    }

    /**
     * 克隆实体
     */
    public clone(): this {
        const cloned = Object.create(Object.getPrototypeOf(this));
        Object.assign(cloned, this);
        cloned.id = this.generateId();
        cloned.createdAt = new Date();
        cloned.updatedAt = new Date();
        cloned.version = 1;
        return cloned;
    }

    /**
     * 转换为普通对象
     */
    public toObject(): any {
        const obj: any = {};
        for (const key in this) {
            if (this.hasOwnProperty(key)) {
                obj[key] = this[key];
            }
        }
        return obj;
    }

    /**
     * 从普通对象创建实体
     */
    public static fromObject<T extends BaseEntity>(this: new () => T, obj: any): T {
        const entity = new this();
        Object.assign(entity, obj);
        return entity;
    }

    /**
     * 比较两个实体是否相等
     */
    public equals(other: BaseEntity): boolean {
        return this.id === other.id;
    }

    /**
     * 获取实体哈希值
     */
    public hashCode(): string {
        return this.id + '_' + this.version;
    }
}

/**
 * 验证结果接口
 */
interface ValidationResult {
    isValid: boolean;
    errors: ValidationError[];
}

/**
 * 验证错误接口
 */
interface ValidationError {
    field: string;
    message: string;
    value?: any;
}
